﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Windows.Forms;
using Microsoft.DirectX.DirectDraw;

namespace gametest
{
    public class DxInitGraphics
    {
        private Control target = null;
        private Device graphicsDevice = null;
        private Clipper graphicsClipper = null;
        private Surface surfacePrimary = null;
        private Surface surfaceSecondary = null;

        public Device DDDevice
        {
            get { return graphicsDevice; }
        }
        public Surface RenderSurface
        {
            get { return surfaceSecondary; }
        }
        public Control Target
        {
            get { return target; }
        }

        public DxInitGraphics(Control renderControl)
        {
            // 0. Save reference to target control 
            this.target = renderControl;

            // 1. Create a graphics device 
            graphicsDevice = new Device();

            // 2. Set the cooperative level of the device
#if DEBUG
            graphicsDevice.SetCooperativeLevel(this.target, CooperativeLevelFlags.Normal);
#else
            graphicsDevice.SetDisplayMode(this.target.MaximumSize.Width, this.target.MaximumSize.Height, 32, 60, true);
            graphicsDevice.SetCooperativeLevel(this.target, CooperativeLevelFlags.FullscreenExclusive);
#endif
            // 3. Create a primary and secondary surface 
            this.CreateSurfaces();
        }

        private void CreateSurfaces()
        {
            SurfaceDescription desc = new SurfaceDescription();
            desc.SurfaceCaps.PrimarySurface = true;
#if !DEBUG
            desc.SurfaceCaps.Flip = true;
            desc.SurfaceCaps.Complex = true;
            desc.BackBufferCount = 1;
#endif
            surfacePrimary = new Surface(desc, graphicsDevice);
            desc.Clear();
#if DEBUG
            desc.Width = surfacePrimary.SurfaceDescription.Width;
            desc.Height = surfacePrimary.SurfaceDescription.Height;
            desc.SurfaceCaps.OffScreenPlain = true;
            surfaceSecondary = new Surface(desc, this.graphicsDevice);
#else
            desc.SurfaceCaps.BackBuffer = true;
            surfaceSecondary = surfacePrimary.GetAttachedSurface(desc.SurfaceCaps);
#endif
            // 4. Create a clipper for the primary surface
            graphicsClipper = new Clipper(graphicsDevice);
            graphicsClipper.Window = target;
            surfacePrimary.Clipper = this.graphicsClipper;
        }

        public void Flip()
        {
            if (!this.target.Created) return;
            if (surfacePrimary == null || surfaceSecondary == null) return;

            // 5. Transfer contents from the secondary surface to the primary surface
#if DEBUG
            surfacePrimary.Draw(surfaceSecondary, DrawFlags.Wait);
#else
            surfacePrimary.Flip(surfaceSecondary, FlipFlags.Wait);
#endif
        }
    }
}
